using System;
using System.IO;
using System.Text;
using Library.Logging;

// NOTE: To read compressed SWF files, you'll need to download SharpZipLib and add a reference to ICSharpCode.SharpZipLib.dll
//       to this project. SharpZipLib can be downloaded from: http://www.icsharpcode.net/OpenSource/SharpZipLib/

namespace ITViet.Web.App_Code
{
  public class SWFFile
  { 
    private Stream stream = null;
    private SWFReader swf = null;
    private string fileName = string.Empty;
    private string signature = string.Empty;
    private byte version = 0;
    private uint fileLength = 0;
    private int frameWidth = 0;
    private int frameHeight = 0;
    private Single frameRate = 0.0F;
    private ushort frameCount = 0;

    #region Properties

    public string FileName
    {
      get { return fileName; }
    }

    public string Signature
    {
      get { return signature; }
    }

    public byte Version
    {
      get { return version; }
    }

    public uint FileLength
    {
      get { return fileLength; }
    }

    public int FrameWidth
    {
      get { return frameWidth; }
    }

    public int FrameHeight
    {
      get { return frameHeight; }
    }

    public Single FrameRate
    {
      get { return frameRate; }
    }

    public ushort FrameCount
    {
      get { return frameCount; }
    }

    #endregion

    #region Constructors

    public SWFFile(string fileName)
    {
      this.fileName = fileName;
      this.stream = new FileStream(this.fileName, FileMode.Open, FileAccess.Read);
      this.swf = new SWFReader(this.stream);

      if (ReadHeader())
      {
        // Just identify the tag types
        // ** This would normally be the place to start processing tags **
        //IdentifyTags();
      }
    }

    #endregion

    private bool ReadHeader()
    {
      // Read file signature
      this.signature = Encoding.ASCII.GetString(this.swf.ReadUI8(3)); // "FWS" or "CWS" for ZLIB compressed (v6.0 or later)
      if (this.signature != "FWS" && this.signature != "CWS")
      {
        WriteLog("Not a valid SWF (Flash) file signature");
        return false;
      }
      // Read file version
      this.version = this.swf.ReadUI8();
      // File length
      this.fileLength = this.swf.ReadUI32();
      // If the file is compressed, this is where the ZLIB decompression ("inflate") begins
      if (this.signature == "CWS")
      {
        // Begin inflating stream
        ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream inflatedStream =
          new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(this.stream);
        swf.Stream = inflatedStream;
      }

      // Frame size
      Rect frameSize = new Rect(swf);
      this.frameWidth = frameSize.XMax;
      this.frameHeight = frameSize.YMax;

      // Frame rate (stored in UI8.UI8 format)
      ushort frameRateMinor = swf.ReadUI8();
      ushort frameRateMajor = swf.ReadUI8();
      this.frameRate = Convert.ToSingle(string.Format("{0}.{1}", frameRateMajor, frameRateMinor));    // TODO: Improve this later

      // Frame count
      this.frameCount = swf.ReadUI16();

      return true;
    }

    public void Close()
    {
      this.stream.Close();
    }

    public static void WriteLog(string description)
    {
      Logger.LogError(description, null, "General", null);
    }
  }
}